import 'package:built_collection/built_collection.dart';
import 'package:equatable/equatable.dart';
import 'package:mobile_app.core/core/domain/entities/dialect.dart';
import 'package:mobile_app.core/core/domain/entities/settings/image_settings.dart';
import 'package:mobile_app.core/core/domain/entities/learning_info/learning_info.dart';
import 'package:mobile_app.core/core/domain/helpers/handle_learning_activity/helper.dart';
import 'package:mobile_app.core/core/domain/services/image_service/service.dart';
import 'package:mobile_app.home.core/core/domain/helpers/get_lexical_item_effective_image_path/helper.dart';
import 'package:mobile_app.home.core/core/domain/helpers/is_lexical_item_safe_to_pronounce/helper.dart';
import 'package:mobile_app.home.learning.training/training_page/domain/entities/card_info/card_info.dart';
import 'package:mobile_app.home.learning.training/training_page/domain/entities/training_exercise.dart';
import 'package:mobile_app.home.learning.training/training_page/domain/entities/training_history_item.dart';

part 'result.dart';

abstract class HandleTypingCardFailure {
  TypingCardFailureHandlingResult call({
    required TypingCardInfo currentCardInfo,
    required BuiltList<TrainingHistoryItem> trainingHistory,
    required ImageSettings imageSettings,
    required Dialect dialect,
    required BuiltMap<Dialect, BuiltSet<String>> unsafeToPronounceLexicalItemTitleMap,
    required LearningInfo learningInfo,
  });
}

class HandleTypingCardFailureImpl implements HandleTypingCardFailure {
  const HandleTypingCardFailureImpl({
    required GetLexicalItemEffectiveImagePath getLexicalItemEffectiveImagePath,
    required IsLexicalItemSafeToPronounce isLexicalItemSafeToPronounce,
    required HandleLearningActivity handleLearningActivity,
    required ImageService imageService,
  })  : _getLexicalItemEffectiveImagePath = getLexicalItemEffectiveImagePath,
        _isLexicalItemSafeToPronounce = isLexicalItemSafeToPronounce,
        _handleLearningActivity = handleLearningActivity,
        _imageService = imageService;

  final GetLexicalItemEffectiveImagePath _getLexicalItemEffectiveImagePath;
  final IsLexicalItemSafeToPronounce _isLexicalItemSafeToPronounce;
  final HandleLearningActivity _handleLearningActivity;
  final ImageService _imageService;

  @override
  TypingCardFailureHandlingResult call({
    required TypingCardInfo currentCardInfo,
    required BuiltList<TrainingHistoryItem> trainingHistory,
    required ImageSettings imageSettings,
    required Dialect dialect,
    required BuiltMap<Dialect, BuiltSet<String>> unsafeToPronounceLexicalItemTitleMap,
    required LearningInfo learningInfo,
  }) {
    final updatedLearningInfo = _handleLearningActivity(
      learningInfo: learningInfo,
    );

    final updatedTrainingHistory = trainingHistory.rebuild((trainingHistory) {
      final trainingHistoryItem = TrainingHistoryItem(
        exercise: TrainingExercise.audio,
        lexicalItemId: currentCardInfo.lexicalItem.id,
        successful: false,
      );

      trainingHistory.add(trainingHistoryItem);
    });

    final imagePath = _getLexicalItemEffectiveImagePath(
      lexicalItem: currentCardInfo.lexicalItem,
      cachedImagePathMap: _imageService.cachedImagePathMap,
      imageEnablementEffective: imageSettings.imageEnablementEffective,
    );

    final safeToPronounce = _isLexicalItemSafeToPronounce(
      lexicalItem: currentCardInfo.lexicalItem,
      dialect: dialect,
      unsafeToPronounceLexicalItemTitleMap: unsafeToPronounceLexicalItemTitleMap,
    );

    final updatedCurrentCardInfo = SubsequentMemorizationCardInfo(
      lexicalItem: currentCardInfo.lexicalItem,
      safeToPronounce: safeToPronounce,
      imagePath: imagePath,
    );

    final result = TypingCardFailureHandlingResult(
      trainingHistory: updatedTrainingHistory,
      currentCardInfo: updatedCurrentCardInfo,
      previousCardInfo: currentCardInfo,
      learningInfo: updatedLearningInfo,
    );

    return result;
  }
}
